package com.markerhub.controller;

import com.markerhub.common.lang.Result;
import com.markerhub.entity.SysBackup;
import com.markerhub.service.SysBackupService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.List;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

/**
 * 系统备份Controller
 */
@Api(tags = "系统备份管理")
@RestController
@RequestMapping("/api/sys-backup")
public class SysBackupController extends BaseController {

    @Autowired
    private SysBackupService sysBackupService;

    /**
     * 获取系统备份列表
     */
    @PreAuthorize("hasAuthority('sys:backup:list')")
    @ApiOperation(value = "获取备份列表", notes = "获取所有系统备份记录，支持分页查询")
    @GetMapping("/list")
    public Result list(@RequestParam(required = false) String backupName) {
        // 使用BaseController中的getPage()方法获取分页参数
        Page<SysBackup> page = getPage();
        // 构建查询条件
        QueryWrapper<SysBackup> wrapper = new QueryWrapper<>();
        if (backupName != null && !backupName.isEmpty()) {
            wrapper.like("backup_name", backupName);
        }
        // 按创建时间倒序排序
        wrapper.orderByDesc("created");
        // 执行分页查询
        Page<SysBackup> pageData = sysBackupService.page(page, wrapper);
        return Result.succ(200, "获取数据备份记录列表成功", pageData);
    }

    /**
     * 查询系统备份
     */
    @PreAuthorize("hasAuthority('sys:backup:list')")
    @ApiOperation(value = "查询系统备份", notes = "根据条件查询系统备份")
    @GetMapping("/query")
    public Result query(@RequestParam(required = false) String backupName) {
        // 复用list方法的查询逻辑
        return list(backupName);
    }

    /**
     * 根据ID获取数据备份记录信息
     */
    @PreAuthorize("hasAuthority('sys:backup:list')")
    @ApiOperation(value = "获取备份详情", notes = "根据ID获取数据备份记录详细信息")
    @GetMapping("/detail/{id}")
    public Result detail(@PathVariable Long id) {
        SysBackup backup = sysBackupService.getById(id);
        return Result.succ(200, "获取数据备份记录信息成功", backup);
    }

    /**
     * 创建数据备份记录
     */
    @PreAuthorize("hasAuthority('sys:backup:add')")
    @ApiOperation(value = "创建数据备份", notes = "新增数据备份记录")
    @PostMapping("/add")
    public Result add(@RequestBody SysBackup backup) {
        // 设置创建时间
        backup.setCreated(new Date());
        // 设置更新时间
        // backup.setUpdated(new Date());
        boolean saved = sysBackupService.save(backup);
        return saved ? Result.succ(200, "创建数据备份记录成功", null) : Result.fail("创建数据备份记录失败");
    }

    /**
     * 更新数据备份记录
     */
    @PreAuthorize("hasAuthority('sys:backup:update')")
    @ApiOperation(value = "更新数据备份", notes = "更新数据备份记录信息")
    @PutMapping("/update")
    public Result update(@RequestBody SysBackup backup) {
        // 设置更新时间
        // backup.setUpdated(new Date());
        boolean updated = sysBackupService.updateById(backup);
        return updated ? Result.succ(200, "更新数据备份记录成功", null) : Result.fail("更新数据备份记录失败");
    }

    /**
     * 删除数据备份记录（单个）
     */
    @PreAuthorize("hasAuthority('sys:backup:delete')")
    @ApiOperation(value = "删除数据备份", notes = "根据ID删除单个数据备份记录")
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Long id) {
        boolean deleted = sysBackupService.removeById(id);
        return deleted ? Result.succ(200, "删除数据备份记录成功", null) : Result.fail("删除数据备份记录失败");
    }
    

    /**
     * 恢复备份
     */
    @PreAuthorize("hasAuthority('sys:backup:restore')")
    @ApiOperation(value = "恢复备份", notes = "根据备份ID恢复系统数据")
    @PutMapping("/restore/{id}")
    public Result restore(@PathVariable Long id) {
        SysBackup backup = sysBackupService.getById(id);
        if (backup == null) {
            return Result.fail("备份记录不存在");
        }
        
        // 实现基本的备份恢复逻辑
        try {
            // 实现备份恢复逻辑
            // 1. 验证备份文件是否存在
            String backupFilePath = backup.getBackupPath();
            File backupFile = new File(backupFilePath);
            if (!backupFile.exists() || !backupFile.isFile()) {
                throw new RuntimeException("备份文件不存在或路径无效: " + backupFilePath);
            }
            
            // 2. 执行数据库恢复操作（这里是模拟实现，实际应该调用数据库恢复服务）
            // 在实际应用中，这里应该:
            // - 备份当前数据库（以防恢复失败）
            // - 关闭相关连接或服务
            // - 执行SQL脚本或还原数据库文件
            // - 重启相关服务
            
            // 模拟数据库恢复过程
            try {
                // 读取备份文件内容（仅作示例，不实际执行）
                String content = new String(Files.readAllBytes(backupFile.toPath()));
                System.out.println("开始执行恢复操作，备份文件大小: " + content.length() + " 字节");
                
                // 模拟恢复执行时间
                TimeUnit.SECONDS.sleep(1);
                
                // 3. 记录恢复操作日志
                System.out.println("备份恢复成功: " + backup.getBackupName() + " (ID: " + backup.getId() + ")");
                
                // 4. 在实际应用中，这里应该发送系统通知
                // notifyService.sendNotification("备份恢复", "备份 " + backup.getBackupName() + " 恢复成功");
                
            } catch (IOException | InterruptedException e) {
                throw new RuntimeException("备份恢复失败: " + e.getMessage(), e);
            }
            
            // 返回成功响应，包含备份信息
            return Result.succ(200, "备份恢复成功", backup);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("恢复备份失败: " + e.getMessage());
        }
    }
    
    /**
     * 下载备份文件
     */
    @PreAuthorize("hasAuthority('sys:backup:download')")
    @ApiOperation(value = "下载备份文件", notes = "下载指定ID的备份文件")
    @GetMapping("/download/{id}")
    public void download(@PathVariable Long id, HttpServletResponse response) {
        SysBackup backup = sysBackupService.getById(id);
        if (backup == null) {
            // 设置错误响应
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            try {
                response.getWriter().write("备份记录不存在");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        
        try {
            // 构建备份文件路径
            String filePath = backup.getBackupPath();
            File backupFile = new File(filePath);
            
            // 检查文件是否存在
            if (!backupFile.exists()) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                response.getWriter().write("备份文件不存在");
                return;
            }
            
            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setContentLengthLong(backupFile.length());
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(backup.getBackupName() + ".sql", "UTF-8"));
            
            // 读取文件并写入响应输出流
            Files.copy(backupFile.toPath(), response.getOutputStream());
            response.getOutputStream().flush();
        } catch (IOException e) {
            e.printStackTrace();
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                response.getWriter().write("下载备份文件失败: " + e.getMessage());
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
